package com.duobaoyu.dby.supply.biz.client.resource.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.duobaoyu.dby.channel.adapter.bean.config.DictionaryConfig;
import com.duobaoyu.dby.common.core.constant.CommonConstants;
import com.duobaoyu.dby.common.core.constant.SecurityConstants;
import com.duobaoyu.dby.common.core.constant.ServiceNameConstants;
import com.duobaoyu.dby.common.core.util.R;
import com.duobaoyu.dby.resource.admin.feign.RemoteResourceDictionaryItemAdminService;
import com.duobaoyu.dby.resource.common.admin.to.config.DictionaryItemTO;
import com.duobaoyu.dby.resource.common.admin.to.config.DictionaryTO;
import com.duobaoyu.dby.resource.remote.common.enums.DictionaryCodeEnum;
import com.duobaoyu.dby.resource.remote.common.to.config.DictionaryConfigTO;
import com.duobaoyu.dby.supply.biz.client.resource.ResourceDictionaryItemAdminClient;
import com.duobaoyu.dby.supply.biz.client.resource.bean.dto.DictionaryItemDTO;
import com.duobaoyu.dby.supply.biz.client.resource.bean.vo.DictionaryItemVO;
import com.duobaoyu.dby.supply.biz.client.resource.bean.vo.DictionaryVO;
import com.duobaoyu.dby.supply.biz.client.resource.converter.ResourceConverter;
import com.duobaoyu.dby.supply.biz.util.RemoteResultCheckUtil;
import com.duobaoyu.dby.supply.core.common.exception.CustomAssert;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;

/**
 * @author liyang
 * @version 1.0.0
 * @ClassName ResourceDictionaryItemAdminClientImpl
 * @createTime 14:35:00 2023/10/08
 */
@Component
@RequiredArgsConstructor
public class ResourceDictionaryItemAdminClientImpl implements ResourceDictionaryItemAdminClient {

    private final RedissonClient redissonClient;
    private final ResourceConverter resourceConverter;
    private final RemoteResourceDictionaryItemAdminService remoteResourceDictionaryItemAdminService;


    @Override
    public boolean createDictionaryItem(DictionaryItemDTO dictionaryItem) {
        R<Boolean> result = remoteResourceDictionaryItemAdminService.save(resourceConverter.toResourceDictionaryItem(dictionaryItem), SecurityConstants.FROM_IN);
        RemoteResultCheckUtil.checkRemoteResult(result, ServiceNameConstants.RESOURCE_SERVICE, dictionaryItem);
        return result.getData();
    }

    @Override
    public boolean updateDictionaryItem(DictionaryItemDTO dictionaryItem) {
        R<Boolean> result = remoteResourceDictionaryItemAdminService.modify(resourceConverter.toResourceDictionaryItem(dictionaryItem), SecurityConstants.FROM_IN);
        RemoteResultCheckUtil.checkRemoteResult(result, ServiceNameConstants.RESOURCE_SERVICE, dictionaryItem);
        return result.getData();
    }

    @Override
    public boolean removeDictionaryItemByIds(List<Long> dictionaryItemIds) {
        R<Boolean> result = remoteResourceDictionaryItemAdminService.remove(dictionaryItemIds, SecurityConstants.FROM_IN);
        RemoteResultCheckUtil.checkRemoteResult(result, ServiceNameConstants.RESOURCE_SERVICE, dictionaryItemIds);
        return result.getData();
    }

    @Override
    public Page<DictionaryItemVO> queryPage(DictionaryItemDTO dictionaryItem) {
        R<Page<DictionaryItemTO>> result = remoteResourceDictionaryItemAdminService.queryPage(resourceConverter.toResourceDictionaryItem(dictionaryItem), SecurityConstants.FROM_IN);
        RemoteResultCheckUtil.checkRemoteResult(result, ServiceNameConstants.RESOURCE_SERVICE, dictionaryItem);
        return resourceConverter.toDictionaryItemPage(result.getData());
    }

    @Override
    public DictionaryVO getDictionaryItemByDictionaryId(Long dictionaryId) {
        R<DictionaryTO> result = remoteResourceDictionaryItemAdminService.getDictionaryItem(dictionaryId, SecurityConstants.FROM_IN);
        RemoteResultCheckUtil.checkRemoteResult(result, ServiceNameConstants.RESOURCE_SERVICE, dictionaryId);
        return resourceConverter.toDictionary(result.getData());
    }

    @Override
    public boolean initializeBloomFilter() {
        List<DictionaryConfig> dictionaryCodes = this.getCacheDictionaryItemByDictionaryCode(DictionaryCodeEnum.BLOOM_FILTER_KEY.getValue());
        if(CollectionUtils.isEmpty(dictionaryCodes)){
            return Boolean.FALSE;
        }
        for (DictionaryConfig dictionaryCode : dictionaryCodes) {
            RBloomFilter<String> bloomFilter = redissonClient.getBloomFilter(dictionaryCode.getItemValue());
            //容量 ， 误判率
            bloomFilter.tryInit(10_000_000L, 0.0001);
        }
        return Boolean.TRUE;
    }

    @Override
    public boolean initializeBloomFilter(Long dictionaryItemId, Long expectedInsertions, Double falseProbability) {
        R<DictionaryItemTO> result = remoteResourceDictionaryItemAdminService.getDictionaryItemById(dictionaryItemId, SecurityConstants.FROM_IN);
        CustomAssert.isTrue(result.getCode() == CommonConstants.SUCCESS, result.getMsg());
        DictionaryItemTO dictionaryItem = result.getData();
        if(Objects.isNull(dictionaryItem)){
            return Boolean.TRUE;
        }
        RBloomFilter<String> bloomFilter = redissonClient.getBloomFilter(dictionaryItem.getItemValue());
        //容量 ， 误判率
        return bloomFilter.tryInit(expectedInsertions, falseProbability);
    }

    @Override
    public List<DictionaryConfig> getCacheDictionaryItemByDictionaryCode(String dictionaryCode) {
        R<List<DictionaryConfigTO>> result = remoteResourceDictionaryItemAdminService.getDictionaryByCode(dictionaryCode, SecurityConstants.FROM_IN);
        RemoteResultCheckUtil.checkRemoteResult(result, ServiceNameConstants.RESOURCE_SERVICE, dictionaryCode);
        return resourceConverter.toDictionaryConfig(result.getData());
    }

}
